package handler

import (
	"../model"
	"../utils"
	"encoding/json"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
)

type _option struct {
	Content   string `json:"content"`
	IsCorrect bool   `json:"is_correct"`
}

type _resData struct {
	ID             uint64    `json:"id"`
	Category       uint64    `json:"category"`
	Score          int64     `json:"score"`
	Subject        string    `json:"subject"`
	Level          uint64    `json:"level"`
	Type           string    `json:"type"`
	FillingAnswers []string  `json:"filling-answers"` //记录填空题的答案
	TrueFalse      bool      `json:"true_or_false"`   //记录判断题的答案
	Options        []_option `json:"options"`         //记录选择题的选项，
	CorrectOptions []string  `json:"correct_options"`
}

func GetQuestion(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	var err error
	var b []byte

	response := Response{}.Default()
	id, _ := strconv.ParseUint(ps.ByName("id"), 10, 64)
	question := model.Question{ID: id}
	response.Body["question"] = question.Get()
	b, err = json.Marshal(response)
	fmt.Printf("question %v \n", response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}

func GetQuestions(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	var err error
	var b []byte

	response := Response{}.Default()
	query := parseQuery(r)
	question := model.Question{Category: query.CategoryID}

	fmt.Printf("query  %v \n ", query )

	response.Body["questions"] = question.GetByCategory(query.Page, query.PageSize)
	response.Body["total"] = question.CountByCategory()

	fmt.Printf("question respone %v \n", response)
	b, err = json.Marshal(response)

	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}

func SaveQuestion(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()

	var resData _resData
	json.Unmarshal([]byte(result), &resData)
	m := model.Question{
		ID:       resData.ID,
		Creator:  utils.GetUserInfoFromContext(r.Context()),
		Score:    resData.Score,
		Level:    resData.Level,
		Subject:  resData.Subject,
		Type:     resData.Type,
		Category: resData.Category,
	}


	switch resData.Type {
	case "truefalse":
		m.SetTrueFalse(resData.TrueFalse)
	case "filling":
		m.SetFillingAnswers(strings.Join(resData.FillingAnswers, "||"))
	}

	response := Response{}.Default()
	id, err := m.Save()
	if err != nil {
		response.Code = StatusNotAcceptable
		response.Message = err.Error()
	}

	//当创建题目成功后，创建选项
	if saveOptions(resData.Options, id) != nil {
		response.Code = StatusNotAcceptable
		response.Message = err.Error()
	}

	if err == nil {
		response.Code = StatusOK
	}

	b, err := json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}

/*
  客户端发来的数据格式：
	options = [
            { content: 'content a ', is_correct: false  },
            { content: 'content b ', is_correct: false  },
            { content: 'content c ', is_correct: true   },
            { content: 'content d ', is_correct: false  },
        ]
   现在需要将这些选项一条一条保存进数据库，并取出正确选项的ID，返回给Question
*/
func saveOptions(options []_option, questionID uint64) error {
	answer := &model.AnswerOption{}
	//在新增选项之前 ，需先将选项与题目之间的关联清除掉，以去除旧的关联
	qao := &model.QuestionAnswerOptions{QuestionID: questionID}
	if err := qao.DeleteByQuestionID(); err != nil {
		return err
	}

	for _, v := range options {
		answer.Content = v.Content
		var id uint64
		var err error

		if id, err = answer.Add(); err != nil {
			return err
		}

		answerops := model.QuestionAnswerOptions{QuestionID: questionID, AnswerOptionID: id, IsCorrect: v.IsCorrect}
		if _, err := answerops.Save(); err != nil {
			return err
		}
	}
	return nil
}

func DeleteQuestion(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	userid := utils.GetUserInfoFromContext(r.Context())

	type parseModel struct {
		IDS []uint64 `json:"ids"`
	}
	var m parseModel

	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()

	json.Unmarshal([]byte(result), &m)

	question := model.Question{}

	response := Response{}.Default()
	var notAllowIDList []string
	var deleteFailedIDList []string
	for _, id := range m.IDS {
		if question.IsCreator(userid, id) {
			if err := question.Remove(id); err != nil {
				deleteFailedIDList = append(deleteFailedIDList, utils.Uint2Str(id))
			}
		} else {
			notAllowIDList = append(notAllowIDList, utils.Uint2Str(id))
		}
	}

	if len(deleteFailedIDList) > 0 {
		response.Code = StatusNotAcceptable
		response.Message = "[ " + strings.Join(deleteFailedIDList, "、") + "] 无法删除，请稍后重新再试！\n"
	}

	if len(notAllowIDList) > 0 {
		response.Code = StatusNotAcceptable
		response.Message = response.Message + "[ " + strings.Join(notAllowIDList, "、") + "] 无法删除，请稍后重新再试！\n"
	}

	b, err := json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}
